public class Code2 {
    // 乘积为正数的最长子数组长度

    public int getMaxLen(int[] nums) {
        // 创建 dp 表
        // 初始化
        // 填表
        // 确定返回值

        // 简单分析题目，这道题和获取子 数组的最大乘积值 比较相似
        // 但是这道题目的要求是要获取到 乘积为正数的最大子数组的长度
        // 所以我们可以先有一个 dp 表：f[i] 表示的是以 i 为结尾的所有子数组中乘积为正数的 最长长度
        int n = nums.length;
        // 这里多创建出了一个虚拟节点
        int[] f = new int[n + 1];
        // 需要注意的是，两数相乘是有负有正的，当负负相乘时仍为正数，对此我们还需要创建出一个表 g[i] 表示以 i 元素为结尾的所有子数组的乘积为 负 的最长 长度
        int[] g = new int[n + 1];

        // 进行初始化操作
        // 这里的表中存放的都是相关数组的 长度 所以将第一个元素都初始化为 0 即可
        f[0] = g[0] = 0;

        // 填表
        for(int i = 1; i <= n; i++){
            // 首先针对 f 表进行分析并填写
            // 此时当得到的数据长度为 1 时，即 nums[i]。有两种情况
            // nums[i] > 0 时 f[i]+1，nums[i] < 0 时 f[i] = 0
            // 此时当获取到的数据长度 大于 1 时。同样有两种情况
            // nums[i] > 0 时 此时需要的是 i 元素之前的数为 正数 此时直接进行 f[i] + 1 即可。 nums[i] < 0 时 此时 就需要 i 元素之前相乘的到的数为 负数 以达到 负负得正 填入到 f 表中
            if(nums[i - 1] > 0){
                f[i] = f[i - 1] + 1;
            }else if(nums[i - 1] < 0){
                // 这里我们需要确定的是 g 表中一定要存有 一个 负值才能达到负负得正的效果
                f[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;
            }
            // 填写 g 表的逻辑与填写 f 表的逻辑很相似只需要反过来即可
            if(nums[i - 1] > 0){
                // 我们要知道 g 表中要存储的是为 负 值的信息，此时的值是大于 0 的，因此需要 g 中包含负数的值依次达到 相乘 为负 的情况
                g[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;
            }else if(nums[i - 1] < 0){
                // 当为负值时，g 表中存储的正是负值，因此负正的负
                g[i] = f[i - 1] + 1;
            }
        }
        int ret = 0;
        for(int j = 1; j <= n; j++){
            ret = Math.max(ret, f[j]);
        }
        return ret;
    }
}
